<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>GBA.js Debugger</title>
<script src="js/util.js"></script>
<script src="resources/console.js"></script>
<link href="resources/console.css" rel="stylesheet">
<script>
window.onmessage = function(message) {
	if (message.origin != document.domain && (message.origin != 'file://' || document.domain)) {
		console.log('Failed XSS');
		return;
	}
	switch (message.data) {
	case 'connect':
		master = message.source;
		initialize(master.gba);
		master.postMessage('connected', document.domain || '*');
		break;
	case 'disconnect':
		master = null;
		gba.DEBUG('Emulator disconnected');
		gbaCon = null;
		gba = null;
		window.close();
		break;
	}
};

function setLogLevel(level, enabled) {
	gba.logLevel &= ~level;
	gba.logLevel |= enabled && level;
};

var gbaCon;
function initialize(gba) {
	window.gba = gba;
	gba.logLevel = gba.LOG_ERROR | gba.LOG_WARN | gba.LOG_DEBUG;
	gbaCon = new Console(gba);
	gba.DEBUG('Debugger initialized');
}

function savestate() {
	gbaCon.pause();
	var state = gba.freeze();
	Serializer.serializePNG(Serializer.serialize(state), master.document.getElementById('screen'), function(url) {
		var img = document.getElementById('saveState');
		img.setAttribute('src', url);
	});
};

function loadSavestate(state) {
	try {
		Serializer.deserializePNG(state, function (result) {
			gba.defrost(result);
			gba.DEBUG('Loaded state');
		});
	} catch (exception) {
		gba.ERROR('Failed to load savestate', exception);
	}
}

window.onload = function() {
	if (window.opener) {
		window.opener.postMessage('connect', document.domain || '*');
	}
}

window.onunload = function() {
	gba.doStep = gba.waitFrame;
	if (window.master) {
		window.master.postMessage('disconnect', document.domain || '*');
	}
}
</script>

</head>
<body><section id="top">
	<section id="consoleContainer">
		<div id="consoleControls">
			<label><input type="checkbox" checked onclick="setLogLevel(gba.LOG_ERROR, this.checked)">ERROR</label>
			<label><input type="checkbox" checked onclick="setLogLevel(gba.LOG_WARN, this.checked)">WARN</label>
			<label><input type="checkbox" onclick="setLogLevel(gba.LOG_STUB, this.checked)">STUB</label>
			<label><input type="checkbox" onclick="setLogLevel(gba.LOG_INFO, this.checked)">INFO</label>
			<label><input type="checkbox" checked onclick="setLogLevel(gba.LOG_DEBUG, this.checked)">DEBUG</label>
		</div>
		<ul id="console"></ul>
		<img id="saveState">
	</section>
	<section id="main">
		<section id="display">
			<select id="debugViewSelector" onchange="gbaCon.setView(gbaCon[this.options[this.selectedIndex].value])">
				<option>None</option>
				<option value="paletteView">Palette</option>
				<option value="tileView">Tile</option>
			</select>
			<div id="debugViewer"></div>
		</section>
		<section id="controls">
			<button onclick="gbaCon.step()">Step</button>
			<button onclick="gbaCon.runVisible()">Run slowly</button>
			<button onclick="gbaCon.runFrame()">Next frame</button>
			<button onclick="gbaCon.run()">Run quickly</button>
			<button onclick="gbaCon.pause()">Pause</button>
		</section>
		<section id="saving">
			<button onclick="document.getElementById('uploadSave').click()">Load savedata</button>
			<input type="file" id="uploadSave" onchange="gba.loadSavedataFromFile(this.files[0])" style="display: none">
			<button onclick="gba.downloadSavedata()">Download savedata</button>
			<button onclick="gba.storeSavedata()">Store savedata</button>
			<button onclick="savestate()">Freeze</button>
			<input type="file" id="uploadSavestate" onchange="loadSavestate(this.files[0])" style="display: none">
			<button onclick="document.getElementById('uploadSavestate').click()">Defrost</button>
		</section>
		<section id="registers">
			<div>
				<h3>GPRs</h3>
				<ol id="gprs">
					<li id="r0">0x00000000</li>
					<li id="r1">0x00000000</li>
					<li id="r2">0x00000000</li>
					<li id="r3">0x00000000</li>
					<li id="r4">0x00000000</li>
					<li id="r5">0x00000000</li>
					<li id="r6">0x00000000</li>
					<li id="r7">0x00000000</li>
					<li id="r8">0x00000000</li>
					<li id="r9">0x00000000</li>
					<li id="r10">0x00000000</li>
					<li id="r11">0x00000000</li>
					<li id="r12">0x00000000</li>
					<li id="r13">0x00000000</li>
					<li id="r14">0x00000000</li>
					<li id="r15">0x00000000</li>
				</ol>
			</div>
			<div>
				<h3>Status bits</h3>
				<ol id="psr">
					<li id="cpsrN">N</li>
					<li id="cpsrZ">Z</li>
					<li id="cpsrC">C</li>
					<li id="cpsrV">V</li>
					<li id="cpsrI">I</li>
					<li id="cpsrT">T</li>
					<li>Mode: <span id="mode">SYSTEM</span></li>
				</ol>
			</div>
		</section>
		<section id="breakpoints">
			<div id="breakpointControls">
				Add breakpoint:
				<input type="text" onchange="gbaCon.addBreakpoint(parseInt(this.value, 16))">
			</div>
			<ul id="breakpointView">
			</ul>
		</section>
	</section>
	<section id="memory">
		<div id="memoryControls">
			<h3>Jump to:</h3>
			<ul>
				<li>
					Region:
					<select onchange="gbaCon.memory.scrollTo(this.options[this.selectedIndex].value * 0x01000000)">
						<option value="0">0x00000000: BIOS</option>
						<option value="2">0x02000000: On-Board RAM</option>
						<option value="3">0x03000000: In-Chip RAM</option>
						<option value="4">0x04000000: I/O</option>
						<option value="5">0x05000000: Palette</option>
						<option value="6">0x06000000: VRAM</option>
						<option value="7">0x07000000: OAM</option>
						<option value="8">0x08000000: Gamepak WS 0</option>
						<option value="10">0x0A000000: Gamepak WS 1</option>
						<option value="12">0x0C000000: Gamepak WS 2</option>
						<option value="14">0x0E000000: Gamepak SRAM</option>
					</select>
				</li>
				<li>
					Address:
					<input type="text" onchange="gbaCon.memory.scrollTo(parseInt(this.value, 16))">
				</li>
			</ul>
		</div>
		<ul id="memoryView"></ul>
	</section>
</section>
</body>
</html>